package com.tydic.borderer.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.IdcardUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tydic.borderer.domain.AgentContract;
import com.tydic.borderer.domain.BorderAgent;
import com.tydic.borderer.domain.BordererInfo;
import com.tydic.borderer.domain.bo.AddBordererAgentBo;
import com.tydic.borderer.domain.bo.BorderAgentByPageBo;
import com.tydic.borderer.domain.bo.RenewContractBo;
import com.tydic.borderer.mapper.AgentContractMapper;
import com.tydic.borderer.mapper.BorderAgentMapper;
import com.tydic.borderer.service.IAgentContractService;
import com.tydic.borderer.service.IBorderAgentService;
import com.tydic.borderer.service.IBordererInfoService;
import com.tydic.common.core.domain.model.LoginUser;
import com.tydic.common.core.enums.*;
import com.tydic.common.core.exception.api.ApiException;
import com.tydic.common.core.utils.ReturnUrlUtil;
import com.tydic.common.satoken.utils.LoginHelper;
import com.tydic.common.web.domain.FileItem;
import com.tydic.common.web.utils.ReplaceWordUtil;
import com.tydic.system.domain.Account;
import com.tydic.system.domain.ContractTemplate;
import com.tydic.system.domain.SysMessage;
import com.tydic.system.domain.req.*;
import com.tydic.system.domain.resp.CreateAndPushResponse;
import com.tydic.system.domain.resp.DocDownloadResponse;
import com.tydic.system.domain.vo.SysOssVo;
import com.tydic.system.service.*;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
@RequiredArgsConstructor
public class BorderAgentServiceImpl implements IBorderAgentService {
    private final ISysMessageService messageService;

    private final IFddService fddService;

    private final ISysOssService sysOssService;

    private final IAgentContractService agentContractService;

    private final IBordererInfoService bordererInfoService;

    private final BorderAgentMapper borderAgentMapper;

    private final ISysUserService sysUserService;

    private final AgentContractMapper agentContractMapper;

    private final IContractTemplateService contractTemplateService;
    @Value("${fdd.returnUrlPrefix}")
    private String returnUrlPrefix;

    @Override
    public Page<BorderAgent> queryAduitSymbolList(BorderAgentByPageBo request) {
        //参数1是分页起始位置，一般是1，参数2：结束位置，    一般都是前端传过来的，查询的数量
        LambdaQueryWrapper<BorderAgent> queryWrapper = new LambdaQueryWrapper<>();
        //条件 eq 指的是相等
        queryWrapper.in(BorderAgent::getApplyStatus, AgentApplyStatusEnum.AGREE.getStatus(), AgentApplyStatusEnum.REVOKING.getStatus(), AgentApplyStatusEnum.NEAR_THE_EXPIRE_DATE.getStatus())
            .eq(BorderAgent::getApplyContractStatus, SignStatusEum.SIGNED.getStatus())
            .eq(BorderAgent::getAgentBordererCardNumber, request.getAgentCardNumber());
        if (StrUtil.isNotEmpty(request.getBordererInfo())) {
            queryWrapper.and(i -> i
                .like(BorderAgent::getBordererName, request.getBordererInfo())
                .or()
                .like(BorderAgent::getBordererCardNumber, request.getBordererInfo())
            );
        }
        return borderAgentMapper.selectPage(request.build(), queryWrapper);
    }

    @Override
    public Page<BorderAgent> queryAduitAgentList(BorderAgentByPageBo request) {
        //参数1是分页起始位置，一般是1，参数2：结束位置，    一般都是前端传过来的，查询的数量
        LambdaQueryWrapper<BorderAgent> queryWrapper = new LambdaQueryWrapper<>();
        //条件 eq 指的是相等
        queryWrapper
            .eq(BorderAgent::getApplyContractStatus, SignStatusEum.SIGNED.getStatus())
            .in(BorderAgent::getApplyStatus, AgentApplyStatusEnum.AGREE.getStatus(), AgentApplyStatusEnum.REVOKING.getStatus(), AgentApplyStatusEnum.NEAR_THE_EXPIRE_DATE.getStatus());
        if (request.getBordererInfo() != null) {
            queryWrapper.and(i -> i
                .like(BorderAgent::getBordererName, request.getBordererInfo())
                .or()
                .like(BorderAgent::getBordererCardNumber, request.getBordererInfo())
            );
        }
        return borderAgentMapper.selectPage(request.build(), queryWrapper);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean addBorderAgent(BorderAgent borderAgent, String userCode) {
        return borderAgentMapper.insertOrUpdate(borderAgent);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean addBorderAgent(BordererInfo bordererInfo, AddBordererAgentBo request) {
        BorderAgent borderAgent = new BorderAgent();
        borderAgent.setBordererAgent(AgentEnableEnum.ENABLE.getStatus());
        borderAgent.setJoinType(AgentJoinTypeEnum.INVITE.getStatus());
        borderAgent.setApplyStatus(AgentApplyStatusEnum.APPLYING.getStatus());

        borderAgent.setBeginTime(DateUtil.parse(request.getBeginTime(), "yyyy-MM-dd"));
        borderAgent.setEndTime(DateUtil.parse(request.getEndTime(), "yyyy-MM-dd"));
        //边民
        borderAgent.setBordererId(bordererInfo.getId());
        borderAgent.setBordererPhone(bordererInfo.getPhoneNumber());
        borderAgent.setBordererName(bordererInfo.getName());
        borderAgent.setBordererCardNumber(bordererInfo.getBordererCardNumber());
        borderAgent.setIdCardNumber(bordererInfo.getIdCardNumber());
        //边民代表
        borderAgent.setAgentBordererId(request.getBordererId());
        borderAgent.setAgentBordererPhone(request.getBordererPhone());
        borderAgent.setAgentBordererName(request.getBordererName());
        borderAgent.setAgentBordererCardNumber(request.getBordererCardNumber());
        borderAgent.setAgentIdCardNumber(request.getIdCardNumber());
        return borderAgentMapper.insertOrUpdate(borderAgent);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public String agree(String id) {
        BorderAgent borderAgent = borderAgentMapper.selectById(id);
        if (borderAgent == null) {
            throw new ApiException("当前边民代表信息不存在");
        }
        return getSignUrl(borderAgent.getId());
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean remove(BorderAgent borderAgent, String userCode, String bordererAgent) {
        return false;
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public void remove(String bordererId) {
        LoginUser currentUser = LoginHelper.getLoginUser();
        BorderAgent agent = borderAgentMapper.getCurrentAgentByBordererId(bordererId);
        if (agent == null) {
            throw new ApiException("解除委托失败");
        }
        // 如果不等于同意，说明正在处理
        if (!StrUtil.equals(agent.getApplyStatus(), AgentApplyStatusEnum.AGREE.getStatus())) {
            SysMessage message = messageService.getMessage(MessageCategoryEnum.REMOVE_AGENT, agent.getId(), currentUser.getUserCode());
            if (message == null) {
                throw new ApiException("您已发起解除委托申请，请等待对方处理");
            } else {
                throw new ApiException("对方已发起解除委托申请，请您处理该事项");
            }
        }
        agent.setApplyStatus(AgentApplyStatusEnum.REVOKING.getStatus());
        borderAgentMapper.insertOrUpdate(agent);
        String bordererName = agent.getBordererName();
        String agentBordererName = agent.getAgentBordererName();
        BordererInfo agentBordererInfo = bordererInfoService.getBordererInfoById(agent.getAgentBordererId());
        // 判断当前用户是否边民代表
        if (StrUtil.equals(currentUser.getUserCode(), agentBordererInfo.getUserCode())) {
            // 如果是边民代表操作，通知对方处理
            BordererInfo otherBordererInfo = bordererInfoService.getBordererInfoById(agent.getBordererId());
            String msg = agentBordererName + "解除与" + bordererName + "授权委托代理";
            messageService.insertMessageHandler(MessageCategoryEnum.REMOVE_AGENT,
                agent.getId(), "解除授权委托代理", msg, otherBordererInfo.getUserCode());
        } else {
            // 如果是边民操作，通知边民代表处理
            String msg = bordererName + "解除与" + agentBordererName + "授权委托代理";
            messageService.insertMessageHandler(MessageCategoryEnum.REMOVE_AGENT,
                agent.getId(), "解除授权委托代理", msg, agentBordererInfo.getUserCode());
        }
    }

    private long countByAgentBordererId(String agentBordererId) {
        return borderAgentMapper.selectCount(Wrappers.lambdaQuery(BorderAgent.class).eq(BorderAgent::getAgentBordererId, agentBordererId).eq(BorderAgent::getApplyContractStatus, "1").in(BorderAgent::getApplyStatus, "0", "3", "5"));
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void agreeRemove(String categoryId) {
        BorderAgent borderAgent = borderAgentMapper.selectById(categoryId);
        if (borderAgent == null) {
            throw new ApiException("操作失败");
        }
        borderAgent.setApplyStatus(AgentApplyStatusEnum.REVOKED.getStatus());
        borderAgentMapper.insertOrUpdate(borderAgent);
        // 判断还有没有边民列表，没有则更新为边民
        if (countByAgentBordererId(borderAgent.getAgentBordererId()) == 0L) {
            BordererInfo bordererInfo = bordererInfoService.getBordererInfoById(borderAgent.getAgentBordererId());
            sysUserService.updateUserType(bordererInfo.getUserCode(), UserTypeEnum.BORDERER.getUserType());
        }
        messageService.handleMessage(MessageCategoryEnum.REMOVE_AGENT, categoryId);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void refuse(String categoryId) {
        BorderAgent borderAgent = borderAgentMapper.selectById(categoryId);
        if (borderAgent == null) {
            throw new ApiException("操作失败");
        }
        borderAgent.setApplyStatus(AgentApplyStatusEnum.FAIL.getStatus());
        borderAgentMapper.insertOrUpdate(borderAgent);
        messageService.handleMessage(MessageCategoryEnum.AGENT, categoryId);
    }

    @Override
    public BorderAgent findByBordererId(BorderAgent borderAgent) {
        LambdaQueryWrapper<BorderAgent> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StrUtil.isNotEmpty(borderAgent.getAgentBordererCardNumber()), BorderAgent::getAgentBordererCardNumber, borderAgent.getAgentBordererCardNumber())
            .eq(StrUtil.isNotEmpty(borderAgent.getBordererCardNumber()), BorderAgent::getBordererCardNumber, borderAgent.getBordererCardNumber())
            .eq(StrUtil.isNotEmpty(borderAgent.getBordererPhone()), BorderAgent::getBordererPhone, borderAgent.getBordererPhone())
            .eq(StrUtil.isNotEmpty(borderAgent.getBordererName()), BorderAgent::getBordererName, borderAgent.getBordererName())
            .eq(StrUtil.isNotEmpty(borderAgent.getBordererId()), BorderAgent::getBordererId, borderAgent.getBordererId())
            .eq(StrUtil.isNotEmpty(borderAgent.getApplyStatus()), BorderAgent::getApplyStatus, borderAgent.getApplyStatus());
        return borderAgentMapper.selectOne(queryWrapper, false);
    }

    @Override
    public FileItem fillContract(BorderAgent borderAgent) {
        Map<String, Object> data = new HashMap<>();
        Map<String, Object> picData = new HashMap<>();

        //委托人信息
        if (borderAgent.getBordererName() != null) {
            data.put("${firstParty}", borderAgent.getBordererName());
        } else {
            throw new ApiException("委托人姓名不能为空");
        }
        if (borderAgent.getIdCardNumber() != null) {
            String sex = "男";
            int genderByIdCard = IdcardUtil.getGenderByIdCard(borderAgent.getIdCardNumber());
            if (genderByIdCard == 0) {
                sex = "女";
            }
            data.put("${firstPartySex}", sex);
            data.put("${firstPartyIdCard}", borderAgent.getIdCardNumber());
        } else {
            throw new ApiException("委托人身份证号、性别不能为空");
        }
        BordererInfo bordererInfo = bordererInfoService.getBordererInfoById(borderAgent.getBordererId());
        if (bordererInfo == null) {
            throw new ApiException("委托人的边民信息不存在");
        } else {
            data.put("${firstPartyBankName}", bordererInfo.getBankName());
            data.put("${firstPartyBankAccount}", bordererInfo.getCardNumber());
        }
        //受委托人信息
        if (borderAgent.getAgentBordererName() != null) {
            data.put("${secondParty}", borderAgent.getAgentBordererName());
        } else {
            throw new ApiException("受委托人姓名不能为空");
        }
        if (borderAgent.getAgentIdCardNumber() != null) {
            String sex = "男";
            int genderByIdCard = IdcardUtil.getGenderByIdCard(borderAgent.getAgentIdCardNumber());
            if (genderByIdCard == 0) {
                sex = "女";
            }
            data.put("${secondPartySex}", sex);
            data.put("${secondPartyIdCard}", borderAgent.getAgentIdCardNumber());
        } else {
            throw new ApiException("受委托人身份证号、性别不能为空");
        }


        if (borderAgent.getBeginTime() != null) {
            String beginTime = DateUtil.format(borderAgent.getBeginTime(), "yyyy-MM-dd");
            String[] split = beginTime.split("-");
            //交货时间delivery
            data.put("${beginYear}", split[0]);
            data.put("${beginMonth}", split[1]);
            data.put("${beginDay}", split[2]);
        } else {
            throw new ApiException("开始时间不能为空");
        }


        if (borderAgent.getBordererName() != null) {
            data.put("${firstPartyAddress}", borderAgent.getBordererName());
        } else {
            throw new ApiException("委托人户籍地不能为空");
        }

        if (borderAgent.getBordererPhone() != null) {
            data.put("${firstPartyPhone}", borderAgent.getBordererPhone());
        } else {
            throw new ApiException("委托人联系电话不能为空");
        }

        if (borderAgent.getEndTime() != null) {
            String endTime = DateUtil.format(borderAgent.getEndTime(), "yyyy-MM-dd");
            String[] split = endTime.split("-");
            //交货时间delivery
            data.put("${endYear}", split[0]);
            data.put("${endMonth}", split[1]);
            data.put("${endDay}", split[2]);
        } else {
            throw new ApiException("结束时间内容不能为空");
        }


        if (borderAgent.getAgentBordererName() != null) {
            data.put("${secondPartyAddress}", borderAgent.getAgentBordererName());
        } else {
            throw new ApiException("受委托人户籍地不能为空");
        }

        if (borderAgent.getAgentBordererPhone() != null) {
            data.put("${secondPartyPhone}", borderAgent.getAgentBordererPhone());
        } else {
            throw new ApiException("受委托人联系电话不能为空");
        }

        //合同编号中的日期和编号

        String format = DateUtil.format(new Date(), "yyyy-MM-dd");
        //签订时间
        String[] formatStr = format.split("-");
        data.put("${year}", formatStr[0]);
        data.put("${month}", formatStr[1]);
        data.put("${day}", formatStr[2]);

        ContractTemplate contractTemplate = new ContractTemplate();
        contractTemplate.setTemplateType(ContractTypeEnum.BORDERER_AGENT_CONTRACT.getType());
        contractTemplate.setTemplateStatus(ContractStatusEnum.USING.getStatus());
        List<ContractTemplate> list = contractTemplateService.queryList(contractTemplate);
        if (CollUtil.isEmpty(list)) {
            throw new ApiException("请联系管理员上传授权委托书（边民代表授权）模板");
        }
        File file = sysOssService.getFile(list.get(list.size() - 1).getTemplateFileName(), list.get(list.size() - 1).getTemplateFileId());
        return ReplaceWordUtil.operateWord(data, picData, file, borderAgent.getId() + "委托书.docx");

    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void uploadAndUpdate(BorderAgent borderAgent) {
        LoginUser currentUser = LoginHelper.getLoginUser();
        if (ObjectUtil.isEmpty(currentUser)) {
            throw new ApiException("登录过期，请重新登录");
        }
        /**
         1、文件填充
         */
        if (borderAgent == null) {
            throw new ApiException("当前申请记录不存在");
        }
        //委托人
        BordererInfo bordererInfoFist = bordererInfoService.getBordererInfoById(borderAgent.getBordererId());
        if (bordererInfoFist == null) {
            throw new ApiException("委托人信息不存在");
        }
        //受委托人
        BordererInfo bordererInfoSecond = bordererInfoService.getBordererInfoById(borderAgent.getAgentBordererId());
        if (bordererInfoSecond == null) {
            throw new ApiException("受委托人信息不存在");
        }
        //关联合同
        AgentContract agentContractInfo = agentContractService.getByAgentId(borderAgent.getId());
        if (agentContractInfo != null) {
            throw new ApiException("当前委托已有合同存在，请勿重复签署");
        }
        //合同文件填充
        FileItem fileItem = fillContract(borderAgent);

        if (fileItem != null) {
            //TODO 2、上传填充好的文件
            String contractFileId = String.valueOf(sysOssService.upload(fileItem.getData(), fileItem.getFileName(), fileItem.getContentType()).getOssId());
            File contractFile = null;
            if (fileItem.getFileName() != null) {
                contractFile = new File(fileItem.getFileName());
                try {
                    FileUtil.writeBytes(fileItem.getData(), contractFile);
                } catch (Exception e) {
                    log.error("multipartFile转File失败");
                    throw new ApiException("文件类型转换失败");
                }
            }
            //TODO 3、上传填充好的文件到法大大平台
            FileUploadRequest fileUploadRequest = new FileUploadRequest();
            if (contractFile != null) {
                fileUploadRequest.setFile(contractFile);
            } else {
                throw new ApiException("文件不存在");
            }

            fileUploadRequest.setFileName(borderAgent.getBordererName()
                + "委托"
                + borderAgent.getAgentBordererName()
                + "授权委托书" + ".docx");

            //上传填充好的合同文件到法大大平台
            String uploadFileId = fddService.upload(fileUploadRequest);

            //TODO 4、更新订单与合同关联信息
            //查询订单信息
            //获取委托方的信息
            Account firstAccount = fddService.getAccountByMobile(currentUser.getMobile());
            if (firstAccount == null) {
                throw new ApiException("委托方未在法大大平台注册");
            }
            //获取受委托方
            Account secondAccount = fddService.getAccountByMobile(borderAgent.getAgentBordererPhone());
            if (secondAccount == null) {
                throw new ApiException("受委托方未在法大大平台注册");
            }

            //TODO 5、更新FileId到订单与合同关联表中
            AgentContract agentContract = new AgentContract();
            //orderId
            agentContract.setAgentId(borderAgent.getId());
            agentContract.setUploadFileId(uploadFileId);
            //填充后的文件id
            agentContract.setContractId(IdUtil.getSnowflakeNextIdStr());
            //填充后的文件FileId
            agentContract.setContractFileId(contractFileId);

            //边民
            agentContract.setFirstPartyId(borderAgent.getBordererId());
            agentContract.setFirstPartyAccountId(firstAccount.getAccountId());
            //边民代表
            agentContract.setSecondPartyId(borderAgent.getBordererId());
            agentContract.setSecondPartyAccountId(secondAccount.getAccountId());
            //签署状态
            agentContract.setFirstPartySign(SignStatusEum.UNSIGNED.getStatus());
            agentContract.setSecondPartySign(SignStatusEum.UNSIGNED.getStatus());
            //总状态
            agentContract.setSignStatus(SignStatusEum.UNSIGNED.getStatus());


            agentContractMapper.insertOrUpdate(agentContract);
        }
    }

    @Override
    public String getSignUrl(String agentId) {
        AgentContract agentContract = agentContractService.getByAgentId(agentId);
        String signUrl = null;
        // 创建（乙方）边民用户获取文档签署链接请求对象
        if (agentContract.getFirstPartySign().equals(SignStatusEum.UNSIGNED.getStatus())) {
            FileGetSignRepeatRequest bordererSignRequest = new FileGetSignRepeatRequest();
            bordererSignRequest.setNotifyNo(agentContract.getFirstPartySignNotify());
            bordererSignRequest.setDocId(agentContract.getDocId());
            bordererSignRequest.setSignerAccountId(agentContract.getFirstPartyAccountId());

            signUrl = fddService.getSignUrl(bordererSignRequest);
            agentContract.setFirstPartySignUrl(signUrl);
        } else if (agentContract.getSecondPartySign().equals(SignStatusEum.UNSIGNED.getStatus())) { //创建(甲方)企业用户获取文档签署链接请求对象
            FileGetSignRepeatRequest secondFileSignRequest = new FileGetSignRepeatRequest();
            secondFileSignRequest.setNotifyNo(agentContract.getSecondPartySignNotify());
            secondFileSignRequest.setDocId(agentContract.getDocId());
            secondFileSignRequest.setSignerAccountId(agentContract.getSecondPartyAccountId());

            signUrl = fddService.getSignUrl(secondFileSignRequest);
            agentContract.setSecondPartySignUrl(signUrl);
        }
        agentContractMapper.insertOrUpdate(agentContract);
        return signUrl;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean createAndPush(BorderAgent borderAgent) {
        AgentContract agentContract = agentContractService.getByAgentId(borderAgent.getId());
        if (agentContract == null) {
            return false;
        }
        //委托方
        LoginUser currentUser = LoginHelper.getLoginUser();
        Account firstAccount = fddService.getAccountByMobile(currentUser.getMobile());
        if (firstAccount == null) {
            throw new ApiException("委托方未在法大大平台实名认证");
        }

        //受委托方
        Account secondAccount = fddService.getAccountByMobile(borderAgent.getAgentBordererPhone());
        if (secondAccount == null) {
            throw new ApiException("受委托方未在法大大平台实名认证");
        }

        CreateAndPushRequest createAndPushRequest = new CreateAndPushRequest();

        createAndPushRequest.setDocTitle("委托授权" + borderAgent.getId());

        List<CreateAndPushRequest.Doc> docs = new ArrayList<>();
        CreateAndPushRequest.Doc doc = null;

        List<String> uploadFileIdList = Arrays.stream(agentContract.getUploadFileId().split(",")).collect(Collectors.toList());
        for (String uploadFileId : uploadFileIdList) {
            doc = new CreateAndPushRequest.Doc();
            doc.setFileId(uploadFileId);
            docs.add(doc);
        }

        createAndPushRequest.setDocList(docs);

        createAndPushRequest.setSenderAccountId(firstAccount.getAccountId());
        createAndPushRequest.setIsAutoArchive(1);
        createAndPushRequest.setExpireDate(DateUtil.format(DateUtil.offsetDay(new Date(), 2), "yyyy-MM-dd"));
        createAndPushRequest.setSignDeadline(DateUtil.format(DateUtil.offsetDay(new Date(), 2), "yyyy-MM-dd"));
        //签署方列表
        List<CreateAndPushRequest.SignerInfo> signerInfos = new ArrayList<>();

        CreateAndPushRequest.SignerInfo signerInfo = null;
        for (int i = 0; i < 2; i++) {
            String notifyNo = IdUtil.getSnowflakeNextIdStr();
            signerInfo = new CreateAndPushRequest.SignerInfo();
            signerInfo.setSignMode(1);
            signerInfo.setNotifyNo(notifyNo);
            signerInfo.setIsPosition(1);
            signerInfo.setIsSendNotify(1);
            signerInfo.setPriority(i);
            //有效期设置为 一小时
            signerInfo.setUrlTimeOut(60);
            //委托人
            if (i == 0) {
                signerInfo.setSignerAccountId(agentContract.getFirstPartyAccountId());

                List<DocSignInfoDTO> docSignInfoDTOS = new ArrayList<>();

                DocSignInfoDTO docSignInfoDTO = new DocSignInfoDTO();
                docSignInfoDTO.setFileId(agentContract.getUploadFileId());
                DocSignInfoDTO.PersonSealDTO personSealDTO = new DocSignInfoDTO.PersonSealDTO();
                personSealDTO.setKeyWord("委托人（签字）：");
                personSealDTO.setKeyWordPolicy(1);
                personSealDTO.setOffsetX(8.0);
                personSealDTO.setOffsetY(8.0);

                docSignInfoDTO.setPersonSealDTO(personSealDTO);
                docSignInfoDTOS.add(docSignInfoDTO);
                signerInfo.setDocSignInfoDTO(docSignInfoDTOS);
                signerInfo.setReturnUrl(ReturnUrlUtil.getInviteBordererUrl(returnUrlPrefix));
                agentContract.setFirstPartySignNotify(notifyNo);
            }
            //受委托人
            if (i == 1) {
                signerInfo.setSignerAccountId(agentContract.getSecondPartyAccountId());

                List<DocSignInfoDTO> docSignInfoDTOS = new ArrayList<>();

                DocSignInfoDTO docSignInfoDTO = new DocSignInfoDTO();
                docSignInfoDTO.setFileId(agentContract.getUploadFileId());
                DocSignInfoDTO.PersonSealDTO personSealDTO = new DocSignInfoDTO.PersonSealDTO();
                personSealDTO.setKeyWord("受委托人（签字）：");
                personSealDTO.setKeyWordPolicy(2);
                personSealDTO.setOffsetX(8.0);
                personSealDTO.setOffsetY(8.0);

                docSignInfoDTO.setPersonSealDTO(personSealDTO);
                docSignInfoDTOS.add(docSignInfoDTO);
                signerInfo.setDocSignInfoDTO(docSignInfoDTOS);
                signerInfo.setReturnUrl(ReturnUrlUtil.getInviteBordererUrl(returnUrlPrefix));
                agentContract.setSecondPartySignNotify(notifyNo);
            }
            signerInfos.add(signerInfo);

        }
        createAndPushRequest.setSignerInfos(signerInfos);
        log.info("创建签署推送请求参数" + JSONObject.toJSONString(createAndPushRequest));
        CreateAndPushResponse andPush = fddService.createAndPush(createAndPushRequest, "/updateAgentSignStatus");
        log.info("创建签署推送返回结果" + JSONObject.toJSONString(andPush));
        if (ObjectUtil.isNotEmpty(andPush)) {
            //更新订单合同关联表信息
            agentContract.setDocId(andPush.getDocId());
            agentContractMapper.insertOrUpdate(agentContract);
        } else {
            return false;
        }

        return true;
    }

    @Override
    public void getContractPageView(String agentId, HttpServletResponse response) {
        AgentContract agentContract = agentContractService.getByAgentId(agentId);
        if (ObjectUtil.isEmpty(agentContract)) {
            throw new ApiException("当前订单合同未生成");
        }
        if (agentContract.getDocId() == null) {
            throw new ApiException("当前合同未生成，请稍后重试");
        }
        String pageViewFileId = getPageViewFileId(agentContract);
        sysOssService.preview(pageViewFileId, response);
    }

    public String getPageViewFileId(AgentContract agentContract) {
        DocDownloadRequest docDownloadRequest = new DocDownloadRequest();
        docDownloadRequest.setDocId(agentContract.getDocId());
        DocDownloadResponse download = fddService.download(docDownloadRequest);
        SysOssVo upload = sysOssService.upload(download(download.getFileUrl()), "测试文件.pdf", "application/pdf");
        agentContract.setContractFileId(String.valueOf(upload.getOssId()));
        agentContractMapper.updateById(agentContract);
        return String.valueOf(upload.getOssId());
    }


    private byte[] download(String url) {
        HttpRequest get = HttpUtil.createGet(url);
        try (HttpResponse response = get.execute()) {
            return response.bodyBytes();
        } catch (Exception e) {
            log.info("下载文件异常", e);
        }
        return null;
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public String inviteBorderer(AddBordererAgentBo request) {
        String signUrl = "";
        //1、查询当前申请的边民信息是否存在
        LoginUser currentUser = LoginHelper.getLoginUser();
        BordererInfo bordererInfo = bordererInfoService.getBordererInfoByUserCode(currentUser.getUserCode());
        if (bordererInfo == null) {
            throw new ApiException("当前边民不存在");
        }

        if (StrUtil.equals(bordererInfo.getBordererCardNumber(), request.getBordererCardNumber())) {
            throw new ApiException("请不要邀请自己");
        }

        //查看当前边民是否已开通免签，如未开通则先开通。

        /*SeachUnwantedAuthSignRequest borderAuthSign = new SeachUnwantedAuthSignRequest();
        borderAuthSign.setAuthorizerFlag(AuthTypeEnum.BORDERER.getType());
        borderAuthSign.setAuthorizerTargetId(borderAccount.getAccountId());
        UnwantedAuthSignStatusResponse borderAuthSignResponse = fddService.searchUnwantedAuthSignStatus(borderAuthSign);
        if (borderAuthSignResponse == null || !NumberUtil.equals(borderAuthSignResponse.getStatus(), UnwantedAuthSignEnum.EFFECT.getType())){
            throw new ApiException("边民未开启免验证签署");
        }

        SeachUnwantedAuthSignRequest enterpriseAuthSign = new SeachUnwantedAuthSignRequest();
        enterpriseAuthSign.setAuthorizerFlag(AuthTypeEnum.ENTERPRISE.getType());
        enterpriseAuthSign.setAuthorizerTargetId(company.getCompanyId());
        UnwantedAuthSignStatusResponse enterpriseResponse = fddService.searchUnwantedAuthSignStatus(enterpriseAuthSign);
        if (enterpriseResponse == null || !NumberUtil.equals(enterpriseResponse.getStatus(), UnwantedAuthSignEnum.EFFECT.getType())){
            throw new ApiException("企业未开启免验证签署");
        }*/


        //2、查询当前边民是否已经存在于边民列表
        long applingCount = countBybordererIdAndApplyStatus(bordererInfo.getId(), AgentApplyStatusEnum.APPLYING.getStatus());
        long renewCount = countBybordererIdAndApplyStatus(bordererInfo.getId(), AgentApplyStatusEnum.RENEW.getStatus());
        long agreeCount = countBybordererIdAndApplyStatus(bordererInfo.getId(), AgentApplyStatusEnum.AGREE.getStatus());
        long nearTheExpireDateCount = countBybordererIdAndApplyStatus(bordererInfo.getId(), AgentApplyStatusEnum.NEAR_THE_EXPIRE_DATE.getStatus());
        long revokingCount = countBybordererIdAndApplyStatus(bordererInfo.getId(), AgentApplyStatusEnum.REVOKING.getStatus());
        if (applingCount > 0L || agreeCount > 0L || revokingCount > 0L || renewCount > 0 || nearTheExpireDateCount > 0) {
            if (applingCount > 0L) {
                throw new ApiException("您当前有邀请委托事项未处理，请处理后再发起邀请");
            }
            if (renewCount > 0L) {
                throw new ApiException("您当前有续签事项未处理，无法发起邀请");
            }
            if (revokingCount > 0L) {
                throw new ApiException("您当前有解除委托事项未处理，请处理后再发起邀请");
            }
            if (agreeCount > 0L || nearTheExpireDateCount > 0) {
                throw new ApiException("您当前是边民代表，无法发起邀请");
            }

        } else {
            // 获取当前边民的边民代表
            BorderAgent currentBorderAgent = getByBordererId(bordererInfo.getId());
            if (currentBorderAgent != null) {
                if (StrUtil.equals(currentBorderAgent.getApplyStatus(), AgentApplyStatusEnum.REVOKING.getStatus())) {
                    throw new ApiException("您正在解除委托中，请完成解除委托后再尝试邀请");
                }
                if (StrUtil.equalsAny(currentBorderAgent.getApplyStatus(), AgentApplyStatusEnum.APPLYING.getStatus(), AgentApplyStatusEnum.AGREE.getStatus())) {
                    AgentContract agentContract = agentContractService.getByAgentId(currentBorderAgent.getId());
                    if (StrUtil.equals(agentContract.getFirstPartySign(), YesOrNo.NO.getStatus())) {
                        return agentContract.getFirstPartySignUrl();
                    } else {
                        throw new ApiException("您已发起一个邀请委托，请等待处理");
                    }
                }
            }
        }

        //3、被邀请人
        BordererInfo bordererInfoAgent = bordererInfoService.getBordererInfoById(request.getBordererId());
        if (bordererInfoAgent == null) {
            throw new ApiException("被邀请人边民不存在，请重新选择");
        }
        BorderAgent invitedBorderAgent = getByBordererId(bordererInfoAgent.getId());
        // 判断邀请对象有没有边民代表，有的话，不能被邀请
        if (invitedBorderAgent != null) {
            throw new ApiException("受邀边民当前状态不可被邀请，请稍后重试");
        }

        BorderAgent borderAgent = new BorderAgent();
//        borderAgent.setBordererAgent(AgentEnableEnum.DISABLE.getStatus());
//        borderAgent.setJoinType(AgentJoinTypeEnum.INVITE.getStatus());
        borderAgent.setApplyStatus(AgentApplyStatusEnum.APPLYING.getStatus());

        borderAgent.setBeginTime(DateUtil.parse(request.getBeginTime(), "yyyy-MM-dd"));
        borderAgent.setEndTime(DateUtil.parse(request.getEndTime(), "yyyy-MM-dd"));
        //边民
        borderAgent.setBordererId(bordererInfo.getId());
        borderAgent.setBordererPhone(currentUser.getMobile());
        borderAgent.setBordererName(bordererInfo.getName());
        borderAgent.setBordererCardNumber(bordererInfo.getBordererCardNumber());
        borderAgent.setIdCardNumber(bordererInfo.getIdCardNumber());
        //边民代表
        borderAgent.setAgentBordererId(request.getBordererId());
        borderAgent.setAgentBordererPhone(request.getBordererPhone());
        borderAgent.setAgentBordererName(request.getBordererName());
        borderAgent.setAgentBordererCardNumber(request.getBordererCardNumber());
        borderAgent.setAgentIdCardNumber(request.getIdCardNumber());
        addBorderAgent(borderAgent, bordererInfoAgent.getUserCode());
        //签订合同
        uploadAndUpdate(borderAgent);
        //验证合同是否上传成功，可以签署 :更具orderCode查询OrderContract（js_sys_order_contract）表中的upload_file_id是否存在即可
        AgentContract agentContract = agentContractService.getByAgentId(borderAgent.getId());
        //签署合同
        if (ObjectUtil.isNotEmpty(agentContract) && agentContract.getUploadFileId() != null) {
            boolean success = this.createAndPush(borderAgent);
            if (!success) {
                throw new ApiException("创建签署失败");
            }
            //获取签署链接（未来接入短信功能）
            signUrl = this.getSignUrl(borderAgent.getId());
        }
        return signUrl;
    }

    private BorderAgent getByBordererId(String bordererId) {
        return borderAgentMapper.selectOne(Wrappers.lambdaQuery(BorderAgent.class).eq(BorderAgent::getBordererId, bordererId).in(BorderAgent::getApplyStatus, "0", "3", "5"), false);
    }

    private long countBybordererIdAndApplyStatus(String bordererId, String applyStatus) {
        return borderAgentMapper.selectCount(Wrappers.lambdaQuery(BorderAgent.class).eq(BorderAgent::getBordererId, bordererId).eq(BorderAgent::getApplyStatus, applyStatus));
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public String renewContract(RenewContractBo request) {
        BorderAgent borderAgent = borderAgentMapper.selectById(request.getId());
        if (borderAgent == null) {
            throw new ApiException("边民代表信息不存在");
        }
        BorderAgent renewBorderAgent = findByAgentBordererIdAndBordererIdAndApplyStatus(borderAgent.getAgentBordererId(), borderAgent.getBordererId(), AgentApplyStatusEnum.RENEW.getStatus());
        if (renewBorderAgent != null) {
            AgentContract agentContract = agentContractService.getByAgentId(renewBorderAgent.getId());
            if (agentContract != null && StrUtil.equals(agentContract.getFirstPartySign(), SignStatusEum.SIGNED.getStatus())) {
                throw new ApiException("您已完成签署，请等待对方处理");
            }
            return getSignUrl(renewBorderAgent.getId());
        }
        renewBorderAgent = new BorderAgent();
        BeanUtil.copyProperties(borderAgent, renewBorderAgent, "id", "beginTime", "endTime", "applyStatus", "applyContractStatus");
        renewBorderAgent.setId(IdUtil.getSnowflakeNextIdStr());
        renewBorderAgent.setBeginTime(DateUtil.parse(request.getBeginTime(), "yyyy-MM-dd"));
        renewBorderAgent.setEndTime(DateUtil.parse(request.getEndTime(), "yyyy-MM-dd"));
        renewBorderAgent.setApplyStatus(AgentApplyStatusEnum.RENEW.getStatus());
        renewBorderAgent.setApplyContractStatus(SignStatusEum.UNSIGNED.getStatus());
        borderAgentMapper.insertOrUpdate(renewBorderAgent);
        uploadAndUpdate(renewBorderAgent);
        //验证合同是否上传成功，可以签署 :更具orderCode查询OrderContract（js_sys_order_contract）表中的upload_file_id是否存在即可
        AgentContract agentContract = agentContractService.getByAgentId(renewBorderAgent.getId());
        String signUrl = "";
        //签署合同
        if (ObjectUtil.isNotEmpty(agentContract) && agentContract.getUploadFileId() != null) {
            boolean success = this.createAndPush(renewBorderAgent);
            if (!success) {
                throw new ApiException("创建签署失败");
            }
            //获取签署链接（未来接入短信功能）
            signUrl = getSignUrl(renewBorderAgent.getId());
        }
        return signUrl;
    }

    private BorderAgent findByAgentBordererIdAndBordererIdAndApplyStatus(String agentBordererId, String bordererId, String applyStatus) {
        return borderAgentMapper.selectOne(Wrappers.lambdaQuery(BorderAgent.class).eq(BorderAgent::getAgentBordererId, agentBordererId).eq(BorderAgent::getBordererId, bordererId).eq(BorderAgent::getApplyStatus, applyStatus), false);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void refuseRemove(String categoryId) {
        BorderAgent borderAgent = borderAgentMapper.selectById(categoryId);
        if (borderAgent == null) {
            throw new ApiException("操作失败");
        }
        borderAgent.setApplyStatus(AgentApplyStatusEnum.AGREE.getStatus());
        borderAgentMapper.insertOrUpdate(borderAgent);
        messageService.handleMessage(MessageCategoryEnum.REMOVE_AGENT, categoryId);
    }

    @Override
    public long getCountByAgentBordererId(String agentBordererId) {
        return borderAgentMapper.selectCount(Wrappers.lambdaQuery(BorderAgent.class).eq(BorderAgent::getAgentBordererId, agentBordererId).eq(BorderAgent::getApplyContractStatus, "1").in(BorderAgent::getApplyStatus, "0", "3", "5"));
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateOutOfDateBorderAgent(String bordererId) {
        List<BorderAgent> borderAgents = borderAgentMapper.findByBordererIdOrAgentBordererId(bordererId, bordererId);
        if (CollUtil.isEmpty(borderAgents)) {
            return;
        }
        long outOfDate = System.currentTimeMillis();
        long nearTheExpireDate = DateUtil.offsetDay(new Date(), 15).getTime();
        for (BorderAgent borderAgent : borderAgents) {
            // 判断结束时间是否已经过期
            if (borderAgent.getEndTime().getTime() < outOfDate) {
                borderAgent.setApplyStatus(AgentApplyStatusEnum.OUT_OF_DATE.getStatus());
                borderAgentMapper.insertOrUpdate(borderAgent);
            }
            // 判断结束时间是否即将过期
            else if (borderAgent.getEndTime().getTime() < nearTheExpireDate) {
                borderAgent.setApplyStatus(AgentApplyStatusEnum.NEAR_THE_EXPIRE_DATE.getStatus());
                borderAgentMapper.insertOrUpdate(borderAgent);
            }
        }
    }

    @Override
    public BorderAgent findByAgentBordererId(String agentBordererId) {
        return borderAgentMapper.getByAgentBordererId(agentBordererId);
    }

    @Override
    public BorderAgent findByBordererId(String bordererId) {
        return borderAgentMapper.getByBordererId(bordererId);
    }

    @Override
    public BorderAgent findById(String id) {
        return borderAgentMapper.selectById(id);
    }

    @Override
    public List<BorderAgent> findBorderAgentsByAgentBordererId(String agentBordererId) {
        return borderAgentMapper.selectList(Wrappers.lambdaQuery(BorderAgent.class).eq(BorderAgent::getAgentBordererId, agentBordererId));
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void invalidPreviousBorderAgent(String id) {
        BorderAgent borderAgent = borderAgentMapper.selectById(id);
        if (borderAgent == null) {
            throw new ApiException("该边民代表不存在");
        }
        List<BorderAgent> borderAgents = borderAgentMapper.findByBordererIdAndAgentBordererId(borderAgent.getBordererId(), borderAgent.getAgentBordererId());
        if (CollUtil.isEmpty(borderAgents)) {
            return;
        }
        // 本次针对续签动作，排除当前的ID，作废之前的有效的边民代表数据
        for (BorderAgent item : borderAgents) {
            if (!StrUtil.equals(item.getId(), borderAgent.getId())) {
                item.setApplyStatus(AgentApplyStatusEnum.INVALID.getStatus());
                borderAgentMapper.insertOrUpdate(item);
            }
        }
    }

    @Override
    public List<BorderAgent> findByBordererIdOrAgentBordererId(String bordererId, String agentBordererId) {
        return borderAgentMapper.findByBordererIdOrAgentBordererId(bordererId, agentBordererId);
    }


}
